﻿// Inner Fire 游戏引擎库
// IPlayable - 通用播放接口
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 所属层级：应用层(4)
// 用于管理游戏中的动画播放。目前只有这个功能，别搞复杂了。
// 以后可能扩展一个音频。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-04-30

#include "playable.h"
#include <klog.h>
#include <knumber.h>

namespace ifire::game {
const Playable Playable::EMPTY = Playable();

Playable::Playable()
    : type(PlayableType::Empty)
    , loop(PlayMethod::None)
    , time(0.0f)
    , clip(nullptr)
    , blend(nullptr)
    , value(0.0f, 0.0f) {}

Playable::Playable(AnimationClip* clip, PlayMethod loop)
    : type(PlayableType::Clip)
    , loop(loop)
    , time(0.0f)
    , clip(clip)
    , blend(nullptr)
    , value(0.0f, 0.0f) {}

Playable::Playable(AnimationBlend* blend, PlayMethod loop)
    : type(PlayableType::Blend)
    , loop(loop)
    , time(0.0f)
    , clip(nullptr)
    , blend(blend)
    , value(0.0f, 0.0f) {}

void Playable::SetFrame(float frame) {
  // 用frame除fps，直接得到时间
  time = frame / clip->GetFps();
}

void Playable::SetTime(float _time) {
  // 直接设置Time
  time = _time;
}

void Playable::AddDeltaTime(float delta_time) {
  // 如果模式是Frame，则不进行任何变化
  if (loop == PlayMethod::Frame) {
    return;
  }

  // 步进当前的时间
  time += delta_time;
}

float Playable::GetFrame() const {
  // 通过时间计算出frame
  float time_pin = time;

  if (loop == PlayMethod::None) {
    // 如果超出限制，则使用最后一项
    if (time_pin > clip->GetDuration()) {
      time_pin = clip->GetDuration();
    }
  } else if (loop == PlayMethod::Loop) {
    // 循环循环
    time_pin = fmod(time_pin, clip->GetDuration());
  }

  float frame = time_pin * clip->GetFps();

  // KLOG("Time:%f, Pin:%f, Duration:%f, Frame:%f, FrameCount:%f,
  // StartFrame:%f", time, time_pin,
  //     clip->GetDuration(), frame, clip->GetFrameCount(), clip->GetStart());

  // 通过Pin计算出应该有的帧数
  return frame;
}

} // namespace ifire::game